#ifndef DATA_ACCEPTOR_H
#define DATA_ACCEPTOR_H

#include "muduo/base/noncopyable.h"
#include "muduo/net/Socket.h"
#include "muduo/net/Channel.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"

namespace ftp
{

/* Acceptor for Data Connection, different from Acceptor (for Control Connection)
 */
class DataAcceptor : muduo::noncopyable
{
public:
	typedef std::function<void(int sockfd, const muduo::net::InetAddress&)> NewConnectionCallback;

	DataAcceptor(muduo::net::EventLoop* loop, const muduo::net::InetAddress& listenAddr, bool reuseport = false);
	~DataAcceptor();

	void setNewConnectionCallback(const NewConnectionCallback& cb)
	{
		newConnectionCallback_ = cb;
	}

	bool createSocketAndListen();
	bool createSocketAndListen(const muduo::net::InetAddress& listenAddr);
	bool createSocketAndListen(const muduo::net::InetAddress& baseAddr, uint16_t maxPort);
	bool createSocketAndListen(uint16_t minPort, uint16_t maxPort);

	bool listening() const { return listening_; }

	std::string listeningIpPort() const
	{
		// Valid when listening() return true
		return listenAddr_.toIpPort();
	}

	const muduo::net::InetAddress& listenAddr() const
	{
		// Valid when listening() return true
		return listenAddr_;
	}

private:
	void handleRead();

	muduo::net::EventLoop* loop_;             // owner EventLoop, i.e. IO loop
	bool listening_;                          // status indicates whether the acceptor_ is listening on a port
	int idleFd_;                              // auxiliary fd 
	bool reuseport_;
	muduo::net::InetAddress listenAddr_;
	NewConnectionCallback newConnectionCallback_;
	muduo::net::Socket acceptSocket_;
	muduo::net::Channel acceptChannel_;
};

} // namespace ftp

#endif // !ACCEPTOR_FOR_DATA_CONNECTION_H
